package practica1.ui.menuBar;

import java.util.ArrayList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import practica1.actions.*;
import practica1.controller.Controller;
import practica1.controller.adapter.ControllerExperimentoAdapter;
import practica1.controller.adapter.ControllerPoblacionAdapter;
import practica1.controller.event.ControllerExperimentoEvent;
import practica1.controller.event.ControllerPoblacionEvent;
import practica1.language.Language;
import practica1.language.LanguageEvent;
import practica1.language.LanguageListener;
import practica1.logic.LogicExperimento;
import practica1.logic.LogicPoblacion;

/**
 * Clase que extiende de JMenuBar y construye todas las opciones del menú
 * @author Miguel González - Ceura
 */
public class BarraMenus extends JMenuBar implements LanguageListener {
    private Controller controlador;
    private JMenu menuExpAbiertos;
    private JMenu menuArchivo;
    private JMenu menuExperimentos;
    private JMenu menuAyuda;
    private JMenu menuHerramientas;
    
    //Sincronizaremos el orden de los submenús según agregamos o quitamos exp.
    private ArrayList<LogicExperimento> experimentosMostrados =
            new ArrayList<LogicExperimento>();
    
    /**
     * Constructor de la barra por defecto
     */
    public BarraMenus() {
        super();
    
        Language.getI().addLanguageListener(this);
        
        //Nos suscribimos a los cambios en las poblaciones del modelo
        controlador = Controller.getInstance();
        controlador.addControllerExperimentoListener(new EscuchadorExperimentos());
        controlador.addControllerPoblacionListener(new EscuchadorPoblaciones());
        
        /*
         * Archivo
         */
        menuArchivo = new JMenu(Language.getI().getP("ARCHIVO"));
        menuArchivo.setMnemonic('A');
        
        // establecer elemento de menú Acerca de...
        JMenuItem itemAbrir = new JMenuItem(new ActionAbrir());
        JMenuItem itemExportarAccess = new JMenuItem(new ActionExportarExcel());
        JMenuItem itemImprimir = new JMenuItem(new ActionImprimir());
        JMenuItem itemSalir = new JMenuItem(new ActionSalir());
        
        menuArchivo.add(itemAbrir);
        menuArchivo.add(itemExportarAccess);
        menuArchivo.add(itemImprimir);
        menuArchivo.add(itemSalir);
        
        add(menuArchivo);
        
        /*
         * Población
         */
        menuExperimentos = new JMenu(Language.getI().getP("EXPERIMENTO"));
        menuExperimentos.setMnemonic('E');
        menuExpAbiertos = new JMenu(Language.getI().getP("EXPERIMENTOS_ABIERTOS"));
        menuExpAbiertos.setMnemonic('X');
        
        menuExperimentos.add(menuExpAbiertos);
        menuExperimentos.add(new JMenuItem(new ActionNuevoExperimento()));
        
        add(menuExperimentos);
        
        //Añadimos los experimentos que tenga abierto el controlador
        for(LogicExperimento ex : controlador.getExperimentosAbiertos()) {
            aniadirExperimento(ex);
        }
        
        /*
         * Herramientas
         */
        menuHerramientas = new JMenu(Language.getI().getP("HERRAMIENTAS"));
        menuHerramientas.setMnemonic('H');
        menuHerramientas.add(new JMenuItem(new ActionOpciones()));
        add(menuHerramientas);
        
        /*
         * Ayuda
         */
        menuAyuda = new JMenu(Language.getI().getP("AYUDA"));
        menuAyuda.setMnemonic('Y');
        JMenuItem itemSobre = new JMenuItem(new ActionSobre());
        menuAyuda.add(itemSobre);
        add(menuAyuda);
    }
    
    /**
     * Añade un experimento y sus poblaciones a la barra
     * @param experimento 
     */
    private void aniadirExperimento(LogicExperimento experimento) {
        JMenu menuExperimento = new JMenu(experimento.getNombreExperimento());
            
        menuExperimento.add(new JMenuItem(new 
                ActionNuevaPoblacion(experimento)));


        ArrayList<LogicPoblacion> poblacionesExperimento =
                experimento.getPoblaciones();

        //Creamos los submenús con todas sus poblaciones
        for(int i=0; i< poblacionesExperimento.size(); i++) {
            JMenu menuPoblacion = new JMenu(
                    poblacionesExperimento.get(i).getNombrePoblacion());

            menuPoblacion.add(new JMenuItem(new ActionMostrarPoblacion(
                    poblacionesExperimento.get(i))));

            menuPoblacion.add(new JMenuItem(new ActionBorrarPoblacion(
                    poblacionesExperimento.get(i))));

            menuExperimento.add(menuPoblacion);
        }

        menuExpAbiertos.add(menuExperimento);
        experimentosMostrados.add(experimento);
    }

    /**
     * Cuando el idioma cambia establecemos las nuevas palabras
     * @param evt LanguageEvent
     */
    @Override
    public void idiomaChange(LanguageEvent evt) {
        menuArchivo.setText(Language.getI().getP("ARCHIVO"));
        menuExperimentos.setText(Language.getI().getP("EXPERIMENTO"));
        menuExpAbiertos.setText(Language.getI().getP("EXPERIMENTOS_ABIERTOS"));
        menuAyuda.setText(Language.getI().getP("AYUDA"));
        menuHerramientas.setText(Language.getI().getP("HERRAMIENTAS"));
    }
    
    /**
     * Escuchamos los experimentos para actualizar la barra
     */
    private class EscuchadorExperimentos extends ControllerExperimentoAdapter {
        /**
         * Cuando se añade un experimento lo agregamos en la barra
         * @param event ControllerExperimentoEvent
         */
        @Override
        public void addedExperimento(ControllerExperimentoEvent event) {
            aniadirExperimento(event.getExperimento());
        }
        
        /**
         * Cuando borramos un experimento lo borramos de la barra
         * @param event ControllerExperimentoEvent
         */
        @Override
        public void removedExperimento(ControllerExperimentoEvent event) {
            LogicExperimento experimento = event.getExperimento();
            
            int posItem = experimentosMostrados.indexOf(experimento);
            
            //Borramos el experimento
            menuExpAbiertos.remove(posItem);
            experimentosMostrados.remove(posItem);
            
        }
    }
    
    /**
     * Escuchamos las poblaciones para actualizar la barra
     */
    private class EscuchadorPoblaciones extends ControllerPoblacionAdapter {
        /**
         * Cuando se añade una población la agregamos a la barra
         * @param event ControllerPoblacionEvent
         */
        @Override
        public void addedPoblacion(ControllerPoblacionEvent event) {
            LogicPoblacion poblacion = event.getPoblacion();
            
            int posItemEx = experimentosMostrados.indexOf(
                    poblacion.getExperimentoPadre());
            
            JMenu menuPoblacion = new 
                    JMenu(poblacion.getNombrePoblacion());
            
            
            menuPoblacion.add(new JMenuItem(
                    new ActionMostrarPoblacion(poblacion)));
            
            menuPoblacion.add(new JMenuItem(new ActionBorrarPoblacion(
                        poblacion)));
            
            menuExpAbiertos.getItem(posItemEx).add(menuPoblacion);
        }

        /**
         * Cuando borramos una población la borramos de la barra
         * @param event ControllerPoblacionEvent
         */
        @Override
        public void removedPoblacion(ControllerPoblacionEvent event) {
            LogicPoblacion poblacion = event.getPoblacion();
            
            int posItemEx = experimentosMostrados.indexOf(
                    poblacion.getExperimentoPadre());
            
            JMenu menuExp = (JMenu)menuExpAbiertos.getItem(posItemEx);
            
            int numPob = menuExp.getItemCount();
            boolean encontrado = false;
            
            int posPoblacion = 0;
            for(int i = 0; i<numPob && !encontrado; i++) {
                if(menuExp.getItem(i).getText().equals(poblacion.getNombrePoblacion())) {
                    encontrado = true;
                   posPoblacion = i;
                }
            }
            
            menuExp.remove(posPoblacion);
        }
    }
    
}
